package com.wusiwei.service.impl;

import com.wusiwei.common.Result;
import com.wusiwei.mapper.InvoiceMapper;
import com.wusiwei.service.InvoiceStatisticsService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 发票统计服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class InvoiceStatisticsServiceImpl implements InvoiceStatisticsService {

    private final InvoiceMapper invoiceMapper;

    @Override
    public Result<Map<String, Object>> getOverallStatistics() {
        try {
            Map<String, Object> result = new HashMap<>();

            // 获取发票总数
            int totalCount = invoiceMapper.countTotal();
            result.put("totalCount", totalCount);

            // 获取发票总金额
            BigDecimal totalAmount = invoiceMapper.sumTotalAmount();
            result.put("totalAmount", totalAmount != null ? totalAmount : BigDecimal.ZERO);

            // 获取发票总税额
            BigDecimal totalTax = invoiceMapper.sumTotalTax();
            result.put("totalTax", totalTax != null ? totalTax : BigDecimal.ZERO);

            // 获取价税合计
            BigDecimal totalAmountWithTax = invoiceMapper.sumTotalAmountWithTax();
            result.put("totalAmountWithTax", totalAmountWithTax != null ? totalAmountWithTax : BigDecimal.ZERO);

            // 获取本月发票数量
            int currentMonthCount = invoiceMapper.countByCurrentMonth();
            result.put("currentMonthCount", currentMonthCount);

            // 获取本月发票金额
            BigDecimal currentMonthAmount = invoiceMapper.sumAmountByCurrentMonth();
            result.put("currentMonthAmount", currentMonthAmount != null ? currentMonthAmount : BigDecimal.ZERO);

            // 获取不同类别发票数量
            List<Map<String, Object>> categoryStats = invoiceMapper.countGroupByCategory();
            result.put("categoryStats", categoryStats);

            // 获取状态分布
            List<Map<String, Object>> statusStats = invoiceMapper.countGroupByStatus();
            result.put("statusStats", statusStats);

            return Result.success(result);
        } catch (Exception e) {
            log.error("获取发票总体统计信息失败", e);
            return Result.error("获取发票总体统计信息失败: " + e.getMessage());
        }
    }

    @Override
    public Result<Map<String, Object>> getStatisticsBySupplier() {
        try {
            Map<String, Object> result = new HashMap<>();

            // 按供应商统计发票数量
            List<Map<String, Object>> countBySupplier = invoiceMapper.countGroupBySupplier();
            result.put("countBySupplier", countBySupplier);

            // 按供应商统计发票金额
            List<Map<String, Object>> amountBySupplier = invoiceMapper.sumAmountGroupBySupplier();
            result.put("amountBySupplier", amountBySupplier);

            // 供应商TOP5（按金额）
            List<Map<String, Object>> top5ByAmount = invoiceMapper.getTop5SuppliersByAmount();
            result.put("top5ByAmount", top5ByAmount);

            // 供应商TOP5（按数量）
            List<Map<String, Object>> top5ByCount = invoiceMapper.getTop5SuppliersByCount();
            result.put("top5ByCount", top5ByCount);

            return Result.success(result);
        } catch (Exception e) {
            log.error("按供应商统计发票失败", e);
            return Result.error("按供应商统计发票失败: " + e.getMessage());
        }
    }

    @Override
    public Result<Map<String, Object>> getStatisticsByCategory() {
        try {
            Map<String, Object> result = new HashMap<>();

            // 按发票类别统计数量
            List<Map<String, Object>> countByCategory = invoiceMapper.countGroupByCategory();
            result.put("countByCategory", countByCategory);

            // 按发票类别统计金额
            List<Map<String, Object>> amountByCategory = invoiceMapper.sumAmountGroupByCategory();
            result.put("amountByCategory", amountByCategory);

            // 计算各类别占比
            if (countByCategory != null && !countByCategory.isEmpty()) {
                int total = countByCategory.stream()
                        .mapToInt(map -> Integer.parseInt(map.get("count").toString()))
                        .sum();

                if (total > 0) {
                    List<Map<String, Object>> percentageByCategory = countByCategory.stream()
                            .map(map -> {
                                Map<String, Object> percentMap = new HashMap<>(map);
                                int count = Integer.parseInt(map.get("count").toString());
                                double percentage = (double) count / total * 100;
                                percentMap.put("percentage", BigDecimal.valueOf(percentage).setScale(2, RoundingMode.HALF_UP));
                                return percentMap;
                            })
                            .collect(Collectors.toList());

                    result.put("percentageByCategory", percentageByCategory);
                }
            }

            return Result.success(result);
        } catch (Exception e) {
            log.error("按发票类别统计失败", e);
            return Result.error("按发票类别统计失败: " + e.getMessage());
        }
    }

    @Override
    public Result<Map<String, Object>> getMonthlyTrend(Integer year) {
        try {
            Map<String, Object> result = new HashMap<>();

            // 如果未指定年份，则使用当前年
            if (year == null) {
                year = LocalDate.now().getYear();
            }

            // 获取指定年份的月度趋势
            List<Map<String, Object>> monthlyTrend = invoiceMapper.getMonthlyTrendByYear(year);
            log.info("查询到{}年的月度趋势数据: {}", year, monthlyTrend);

            // 如果没有查询到数据，记录警告但不生成模拟数据
            if (monthlyTrend == null || monthlyTrend.isEmpty()) {
                log.warn("未查询到月度趋势数据，返回空数据");
                monthlyTrend = new ArrayList<>();
            }

            // 确保所有月份都有数据，没有数据的月份设为0
            Map<Integer, Map<String, Object>> monthMap = new HashMap<>();

            // 初始化12个月的数据
            for (int i = 1; i <= 12; i++) {
                Map<String, Object> monthData = new HashMap<>();
                monthData.put("month", String.format("%d-%02d", year, i));
                monthData.put("count", 0);
                monthData.put("amount", BigDecimal.ZERO);
                monthData.put("tax", BigDecimal.ZERO);
                monthData.put("totalAmount", BigDecimal.ZERO);
                monthMap.put(i, monthData);
            }

            // 用查询结果更新月度数据
            if (monthlyTrend != null) {
                for (Map<String, Object> data : monthlyTrend) {
                    // 从月份字符串中提取月份数字，例如 "2023-01" 提取为 1
                    int month;
                    if (data.get("month") instanceof String) {
                        String monthStr = (String) data.get("month");
                        if (monthStr.contains("-")) {
                            month = Integer.parseInt(monthStr.split("-")[1]);
                        } else {
                            month = Integer.parseInt(monthStr);
                        }
                    } else if (data.get("month") instanceof Integer) {
                        month = (Integer) data.get("month");
                    } else if (data.get("month") instanceof BigDecimal) {
                        month = ((BigDecimal) data.get("month")).intValue();
                    } else {
                        month = Integer.parseInt(String.valueOf(data.get("month")));
                    }

                    monthMap.put(month, data);
                }
            }

            // 转换为列表，并按月份排序
            List<Map<String, Object>> sortedMonthlyTrend = monthMap.values().stream()
                    .sorted(Comparator.comparingInt(m -> {
                        String monthStr = String.valueOf(m.get("month"));
                        if (monthStr.contains("-")) {
                            return Integer.parseInt(monthStr.split("-")[1]);
                        } else {
                            return Integer.parseInt(monthStr);
                        }
                    }))
                    .collect(Collectors.toList());

            result.put("year", year);
            result.put("monthlyTrend", sortedMonthlyTrend);

            return Result.success(result);
        } catch (Exception e) {
            log.error("获取月度发票金额趋势失败", e);
            return Result.error("获取月度发票金额趋势失败: " + e.getMessage());
        }
    }
} 